home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / Goodies Disk / Glypha.src / Code ƒ / D-GameUtils.p < prev    next >
Encoding:
Text File  |  1991-02-06  |  29.6 KB  |  957 lines  |  [TEXT/PJMM]

  1. {This code was written by John Calhoun of Soft Dorothy Software.  Code is ©1990 john calhoun}
  2. {Feel free to read over the code, learn from it, etc.}
  3. {If the code helps you or if you borrow portions of it, please send $15 to:}
  4. {john calhoun}
  5. {1201 Oread #4}
  6. {Lawrence, KS 66044}
  7. {So long as this header remains, feel free to distribute this code.}
  8.  
  9. unit GameUtils;
  10.  
  11. interface
  12.  
  13.     uses
  14.         Dialogs, Sound;
  15.  
  16.     const
  17.         liftAmount = -8;
  18.         fallAmount = 1;
  19.         maxFall = 10;
  20.         maxThrust = 16;
  21.         defaultNum = 4;
  22.  
  23.         upperLevel = 0;
  24.         lowerLevel = 1;
  25.         upperEye = 2;
  26.         lowerEye = 3;
  27.  
  28.         fastest = 0;
  29.         fast = 1;
  30.         slow = 3;
  31.         slowest = 4;
  32.  
  33.         source = 0;
  34.         mask = 1;
  35.  
  36.     type
  37.         GameObject = record
  38.                 oldDest, dest, wholeRect: Rect;
  39.                 horiVel, vertVel: Integer;
  40.                 facing: Integer;
  41.                 mode, otherMode, tempInt: Integer;
  42.                 state, otherState: Boolean;
  43.             end;
  44.  
  45.         Bolt = record
  46.                 levelStriking: Integer;
  47.                 leftMode, rightMode: Integer;
  48.                 leftBolts, rightBolts: array[0..3, 0..3, 0..11] of Point;
  49.             end;
  50.  
  51.     var
  52.         {Here follow all the major global variables                            }
  53.         {(yes, there are quite a few)                                                        }
  54.         {Here are then menu handles                                                            }
  55.         AppleMenu, GameMenu, OptionsMenu: MenuHandle;
  56.  
  57.         {The boolean vars often keep track of the game state        }
  58.         playing, pausing, keyboardControl, soundOn, onFastMachine: Boolean;
  59.         deadAndGone, scoresChanged, inhibitSound, doneFlag: Boolean;
  60.         onward, keyStillDown, stonesSliding: Boolean;
  61.  
  62.         {Integers keep track of numbers, level, modes, etc...        }
  63.         numberOfStones, levelOn, mortals, oldDirection: Integer;
  64.         beastsKilled, beastsActive, totalToKill, levelStart, mortalsStart: Integer;
  65.         delayFor, startStone, playMask, growRate, numberOfEnemies: Integer;
  66.  
  67.         {Score is LongInt for the 12 yr old kids that top    36727    }
  68.         gameCycle, score, oldScore, nextMortal, lastLoopTime: LongInt;
  69.  
  70.         {Keep track of the name last entered for the high score    }
  71.         nameUsing: Str255;
  72.  
  73.         {And the ahnk (SP?) cursor variable                                            }
  74.         ahnkCursor: CursHandle;
  75.  
  76.         {Here follow the offscreen bitmap and window variables    }
  77.         mainWndo: WindowPtr;
  78.         playRgn, obeliskRgn1, obeliskRgn2: RgnHandle;
  79.         offEnemyArea, offVirginArea, offLoadArea, offPlayerArea: Rect;
  80.         offEnemyMap, offVirginMap, offLoadMap, offPlayerMap: BitMap;
  81.         offEnemyPort, offVirginPort, offLoadPort, offPlayerPort: GrafPtr;
  82.         offEnemyBits, offVirginBits, offLoadBits, offPlayerBits: Ptr;
  83.  
  84.         {Here are some of the object definition records                    }
  85.         theEye, theHand, thePlayer: GameObject;
  86.         lightning: Bolt;
  87.  
  88.         {Miscellaneous rects for the score box, platforms, etc..}
  89.         scoreGrabRect, scoreDropRect, littleTombRect, playRect: Rect;
  90.         upperTombRect1, upperTombRect2: Rect;
  91.  
  92.         {For the digitized sound                                                                }
  93.         chanPtr: sndchannelptr;
  94.  
  95.         {Arrays hold hiscores made and read from .RSRC fork            }
  96.         hiScores: array[1..10] of LongInt;
  97.         hiStrings: array[1..10] of Str255;
  98.  
  99.         {These vars hold info on the enemies                                        }
  100.         theEnemies: array[0..9] of GameObject;
  101.         enemyLift: array[0..2] of Integer;
  102.  
  103.         {These vars hold locations of all artwork on offscreens    }
  104.         tombRects: array[-5..6] of Rect;
  105.         playerRects: array[0..3, 0..5] of Rect;
  106.         enemyRects: array[0..2, 0..5, 0..1, 0..1] of Rect;
  107.         boneRects: array[0..1, 6..7, 0..1] of Rect;
  108.         absoluteRects: array[0..1, 0..5] of Rect;
  109.         eyeRects: array[0..9] of Rect;
  110.         handRects: array[0..1, 0..1] of Rect;
  111.         ankRects: array[0..15, 0..1] of Rect;
  112.         eggRects, gameoverRects, flameRect: array[0..1] of Rect;
  113.         running: array[-16..16, 0..1, 0..1] of Integer;
  114.         idleLanded: array[-16..16] of Integer;
  115.         gliding: array[-16..16, 0..1] of Integer;
  116.         impacted: array[-70..16] of Integer;
  117.  
  118.     procedure NewLightning;
  119.     procedure StrikeLightning (whichLevel: Integer);
  120.     procedure DoTheSound (whichOne: Str255; asynch: Boolean);
  121.     function DoRandom (range: Integer): Integer;
  122.     procedure ChangeRect;
  123.     procedure DrawPlayer (newRect, oldRect: Rect);
  124.     procedure DrawBeasts;
  125.     procedure DrawHand;
  126.     procedure RedoTheBackground;
  127.     procedure ShowScore;
  128.     procedure DoTheHoopla;
  129.     procedure CheckExtraMortal;
  130.     procedure ReDrawHiScores;
  131.     procedure ReadInScores;
  132.     procedure WriteOutScores;
  133.     procedure FinalScore;
  134.     procedure DoHelpScreen;
  135.     procedure FlushTheScores;
  136.  
  137. {=================================}
  138.  
  139. implementation
  140.  
  141. {=================================}
  142.  
  143.     procedure NewLightning;
  144.         const
  145.             upperHeight = 125;
  146.             lowerHeight = 296;
  147.             upperEyeHeight = 75;
  148.             lowerEyeHeight = 175;
  149.             upperDelta = upperHeight - 141;
  150.             lowerDelta = lowerHeight - 141;
  151.             upperEyeDelta = upperEyeHeight - 141;
  152.             lowerEyeDelta = lowerEyeHeight - 141;
  153.             pylonToCenter = 124;
  154.         var
  155.             index, index2, travel, hori, vert: Integer;
  156.     begin
  157.         with lightning do
  158.             begin
  159.                 levelStriking := upperLevel;
  160.                 leftMode := DoRandom(4);
  161.                 rightMode := DoRandom(4);
  162.                 for index := 0 to 3 do
  163.                     begin
  164.                         SetPt(leftBolts[upperLevel, index, 0], 132, 141);
  165.                         SetPt(rightBolts[upperLevel, index, 0], 378, 141);
  166.                         SetPt(leftBolts[lowerLevel, index, 0], 132, 141);
  167.                         SetPt(rightBolts[lowerLevel, index, 0], 378, 141);
  168.                         SetPt(leftBolts[upperEye, index, 0], 132, 141);
  169.                         SetPt(rightBolts[upperEye, index, 0], 378, 141);
  170.                         SetPt(leftBolts[lowerEye, index, 0], 132, 141);
  171.                         SetPt(rightBolts[lowerEye, index, 0], 378, 141);
  172.                     end;
  173.                 for index := 0 to 3 do
  174.                     for index2 := 1 to 10 do
  175.                         begin
  176.                             travel := (6 - ABS(index2 - 6)) * 5;
  177.                             hori := 132 + (index2 * (pylonToCenter div 12));
  178.                             vert := 141 + (index2 * (upperDelta div 12));
  179.                             vert := vert + DoRandom(travel * 2) - travel;
  180.                             SetPt(leftBolts[upperLevel, index, index2], hori, vert);
  181.                             hori := 380 - (index2 * (pylonToCenter div 12));
  182.                             vert := 141 + (index2 * (upperDelta div 12));
  183.                             vert := vert + DoRandom(travel * 2) - travel;
  184.                             SetPt(rightBolts[upperLevel, index, index2], hori, vert);
  185.                             hori := 132 + (index2 * (pylonToCenter div 12));
  186.                             vert := 141 + (index2 * (lowerDelta div 12));
  187.                             vert := vert + DoRandom(travel * 2) - travel;
  188.                             SetPt(leftBolts[lowerLevel, index, index2], hori, vert);
  189.                             hori := 380 - (index2 * (pylonToCenter div 12));
  190.                             vert := 141 + (index2 * (lowerDelta div 12));
  191.                             vert := vert + DoRandom(travel * 2) - travel;
  192.                             SetPt(rightBolts[lowerLevel, index, index2], hori, vert);
  193.  
  194.                             hori := 132 + (index2 * (pylonToCenter div 12));
  195.                             vert := 141 + (index2 * (upperEyeDelta div 12));
  196.                             vert := vert + DoRandom(travel * 2) - travel;
  197.                             SetPt(leftBolts[upperEye, index, index2], hori, vert);
  198.                             hori := 380 - (index2 * (pylonToCenter div 12));
  199.                             vert := 141 + (index2 * (upperEyeDelta div 12));
  200.                             vert := vert + DoRandom(travel * 2) - travel;
  201.                             SetPt(rightBolts[upperEye, index, index2], hori, vert);
  202.                             hori := 132 + (index2 * (pylonToCenter div 12));
  203.                             vert := 141 + (index2 * (lowerEyeDelta div 12));
  204.                             vert := vert + DoRandom(travel * 2) - travel;
  205.                             SetPt(leftBolts[lowerEye, index, index2], hori, vert);
  206.                             hori := 380 - (index2 * (pylonToCenter div 12));
  207.                             vert := 141 + (index2 * (lowerEyeDelta div 12));
  208.                             vert := vert + DoRandom(travel * 2) - travel;
  209.                             SetPt(rightBolts[lowerEye, index, index2], hori, vert);
  210.                         end;
  211.                 for index := 0 to 3 do
  212.                     begin
  213.                         SetPt(leftBolts[upperLevel, index, 11], 256, upperHeight);
  214.                         SetPt(rightBolts[upperLevel, index, 11], 254, upperHeight);
  215.                         SetPt(leftBolts[lowerLevel, index, 11], 256, lowerHeight);
  216.                         SetPt(rightBolts[lowerLevel, index, 11], 254, lowerHeight);
  217.                         SetPt(leftBolts[upperEye, index, 11], 256, upperEyeHeight);
  218.                         SetPt(rightBolts[upperEye, index, 11], 254, upperEyeHeight);
  219.                         SetPt(leftBolts[lowerEye, index, 11], 256, lowerEyeHeight);
  220.                         SetPt(rightBolts[lowerEye, index, 11], 254, lowerEyeHeight);
  221.                     end;
  222.             end;
  223.     end;
  224.  
  225. {=================================}
  226.  
  227.     procedure StrikeLightning;
  228.         var
  229.             index: Integer;
  230.             isPoint, wasPoint: Point;
  231.             savedPort: GrafPtr;
  232.     begin
  233.         GetPort(savedPort);
  234.         SetPort(mainWndo);
  235.         InvertRgn(obeliskRgn1);
  236.         InvertRgn(obeliskRgn2);
  237.         PenNormal;
  238.         PenSize(2, 2);
  239.         PenMode(patXOr);
  240.         with lightning do
  241.             begin
  242.                 leftMode := DoRandom(4);
  243.                 rightMode := DoRandom(4);
  244.                 for index := 1 to 11 do
  245.                     begin
  246.                         isPoint := leftBolts[whichLevel, leftMode, index];
  247.                         wasPoint := leftBolts[whichLevel, leftMode, index - 1];
  248.                         MoveTo(wasPoint.h, wasPoint.v);
  249.                         LineTo(isPoint.h - 2, isPoint.v);
  250.                         isPoint := rightBolts[whichLevel, leftMode, index];
  251.                         wasPoint := rightBolts[whichLevel, leftMode, index - 1];
  252.                         MoveTo(wasPoint.h, wasPoint.v);
  253.                         LineTo(isPoint.h + 2, isPoint.v);
  254.                     end;
  255.                 for index := 1 to 11 do
  256.                     begin
  257.                         isPoint := leftBolts[whichLevel, leftMode, index];
  258.                         wasPoint := leftBolts[whichLevel, leftMode, index - 1];
  259.                         MoveTo(wasPoint.h, wasPoint.v);
  260.                         LineTo(isPoint.h - 2, isPoint.v);
  261.                         isPoint := rightBolts[whichLevel, leftMode, index];
  262.                         wasPoint := rightBolts[whichLevel, leftMode, index - 1];
  263.                         MoveTo(wasPoint.h, wasPoint.v);
  264.                         LineTo(isPoint.h + 2, isPoint.v);
  265.                     end;
  266.             end;
  267.         InvertRgn(obeliskRgn1);
  268.         InvertRgn(obeliskRgn2);
  269.         SetPort(savedPort);
  270.     end;
  271.  
  272. {=================================}
  273.  
  274.     procedure DoTheSound;
  275.         var
  276.             theSnd: Handle;
  277.             err: OSErr;
  278.     begin
  279.         if (soundOn) then
  280.             begin
  281.                 theSnd := GetNamedResource('snd ', whichOne);
  282.                 if (theSnd <> nil) and (ResError = noErr) then
  283.                     begin
  284.                         if (chanPtr <> nil) then
  285.                             begin
  286.                                 err := SndDisposeChannel(chanPtr, TRUE);
  287.                                 chanPtr := nil;
  288.                             end;
  289.                         if (asynch = true) and (SndNewChannel(chanPtr, 0, initMono, nil) = noErr) then
  290.                             err := SndPlay(chanPtr, theSnd, TRUE)
  291.                         else
  292.                             err := SndPlay(nil, theSnd, FALSE);
  293.                     end;
  294.             end;
  295.     end;
  296.  
  297. {=================================}
  298.  
  299.     function DoRandom;
  300.         var
  301.             rawResult: LongInt;
  302.     begin
  303.         rawResult := Abs(Random);
  304.         DoRandom := (rawResult * range) div 32768
  305.     end;
  306.  
  307. {=================================}
  308.  
  309.     procedure ChangeRect;
  310.         var
  311.             hori, vert: Integer;
  312.     begin
  313.         with thePlayer do
  314.             begin
  315.                 hori := dest.left;
  316.                 vert := dest.top;
  317.                 if (mode < 6) then
  318.                     dest := absoluteRects[facing, mode]
  319.                 else
  320.                     begin
  321.                         SetRect(dest, 0, 0, 44, 23);
  322.                         dest.top := dest.top + 15;
  323.                         dest.bottom := dest.bottom + 15;
  324.                     end;
  325.                 dest.left := dest.left + hori;
  326.                 dest.right := dest.right + hori;
  327.                 dest.top := dest.top + vert;
  328.                 dest.bottom := dest.bottom + vert;
  329.             end;
  330.     end;
  331.  
  332. {=================================}
  333.  
  334.     procedure DrawPlayer;
  335.         var
  336.             index, hori, vert: integer;
  337.             dummyLong: LongInt;
  338.             standInRect, standInRect2, tempRect: Rect;
  339.     begin
  340.         with thePlayer do
  341.             case mode of
  342.                 0..5: 
  343.                     begin
  344.                         UnionRect(oldRect, newRect, wholeRect);
  345.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  346.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, playerRects[facing, mode], playerRects[facing + 2, mode], newRect);
  347.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  348.                         if (otherState) then
  349.                             begin
  350.                                 mode := 6;
  351.                                 CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  352.                                 hori := newRect.left;
  353.                                 vert := newRect.top;
  354.                                 SetRect(newRect, 0, 0, 48, 38);
  355.                                 tempRect := newRect;
  356.                                 newRect.left := newRect.left + hori;
  357.                                 newRect.right := newRect.right + hori;
  358.                                 newRect.top := newRect.top + vert;
  359.                                 newRect.bottom := newRect.bottom + vert;
  360.                                 dest := newRect;
  361.                                 tempRect.left := tempRect.left + 232;
  362.                                 tempRect.right := tempRect.right + 232;
  363.                                 tempRect.top := tempRect.top + 306;
  364.                                 tempRect.bottom := tempRect.bottom + 306;
  365.                                 SetPort(offLoadPort);
  366.                                 for index := 1 to 10 do
  367.                                     begin
  368.                                         EraseRect(tempRect);
  369.                                         CopyBits(offVirginMap, offLoadMap, newRect, tempRect, srcCopy, nil);
  370.                                         CopyMask(offLoadMap, offPlayerMap, offLoadMap, tempRect, boneRects[facing, mode, 1], newRect);
  371.                                         CopyBits(offLoadMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  372.                                         Delay(1, dummyLong);
  373.                                         CopyBits(offVirginMap, offLoadMap, newRect, newRect, srcCopy, nil);
  374.                                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, boneRects[facing, mode, 0], boneRects[facing, mode, 1], newRect);
  375.                                         CopyBits(offLoadMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  376.                                     end;
  377.                                 CopyBits(offVirginMap, mainWndo^.portBits, newRect, newRect, srcCopy, playRgn);
  378.                             end;
  379.                     end;
  380.                 6: 
  381.                     begin
  382.                         UnionRect(oldRect, newRect, wholeRect);
  383.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  384.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, boneRects[facing, mode, 0], boneRects[facing, mode, 1], newRect);
  385.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  386.                     end;
  387.                 7..100: 
  388.                     begin
  389.                         UnionRect(oldRect, newRect, wholeRect);
  390.                         CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  391.                         standInRect := boneRects[facing, 7, 0];
  392.                         standInRect2 := boneRects[facing, 7, 1];
  393.                         vert := dest.bottom - dest.top;
  394.                         standInRect.bottom := standInRect.top + vert;
  395.                         standInRect2.bottom := standInRect2.top + vert;
  396.                         CopyMask(offPlayerMap, offPlayerMap, offLoadMap, standInRect, standInRect2, newRect);
  397.                         CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  398.                     end;
  399.                 otherwise
  400.                     begin
  401.                     end;
  402.             end;
  403.     end;
  404.  
  405. {=================================}
  406.  
  407.     procedure DrawHand;
  408.     begin
  409.         with theHand do
  410.             begin
  411.                 UnionRect(oldDest, dest, wholeRect);
  412.                 CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  413.                 CopyMask(offPlayerMap, offPlayerMap, offLoadMap, handRects[mode, source], handRects[mode, mask], dest);
  414.                 CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  415.             end;
  416.     end;
  417.  
  418. {=================================}
  419.  
  420.     procedure DrawBeasts;
  421.         var
  422.             index: Integer;
  423.             otherRect, otherMask, tempSrc, tempMask: Rect;
  424.     begin
  425. {swap flames on background}
  426.         CopyBits(offVirginMap, offLoadMap, flameRect[0], flameRect[0], srcCopy, nil);
  427.         CopyBits(offVirginMap, offVirginMap, flameRect[1], flameRect[0], srcCopy, nil);
  428.         CopyBits(offLoadMap, offVirginMap, flameRect[0], flameRect[1], srcCopy, nil);
  429.  
  430. {copy all neccesary background rects to the load map}
  431.         with theEye do
  432.             if (mode > 0) then
  433.                 begin
  434.                     UnionRect(oldDest, dest, wholeRect);
  435.                     CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  436.                 end;
  437.  
  438.         for index := 1 to numberOfEnemies do
  439.             with theEnemies[index] do
  440.                 begin
  441.                     UnionRect(oldDest, dest, wholeRect);
  442.                     CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, nil);
  443.                     oldDest := dest;
  444.                 end;
  445.  
  446. {copy the beasts through their masks onto the load map}
  447.         for index := 1 to numberOfEnemies do
  448.             with theEnemies[index] do
  449.                 begin
  450.                     if (mode < 6) then
  451.                         begin
  452.                             if (mode < 0) then
  453.                                 begin
  454.                                     tempSrc := eggRects[0];
  455.                                     tempMask := eggRects[1];
  456.                                     tempSrc.bottom := tempSrc.top + (dest.bottom - dest.top);
  457.                                     tempMask.bottom := tempMask.top + (dest.bottom - dest.top);
  458.                                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, tempSrc, tempMask, dest);
  459.                                 end
  460.                             else
  461.                                 CopyMask(offEnemyMap, offEnemyMap, offLoadMap, enemyRects[otherMode, mode, facing, 0], enemyRects[otherMode, mode, facing, 1], dest)
  462.                         end
  463.                     else
  464.                         begin
  465.                             otherRect := enemyRects[otherMode, 1, facing, source];
  466.                             otherRect.bottom := otherRect.top + (dest.bottom - dest.top);
  467.                             otherMask := enemyRects[otherMode, 1, facing, mask];
  468.                             otherMask.bottom := otherMask.top + (dest.bottom - dest.top);
  469.                             CopyMask(offEnemyMap, offEnemyMap, offLoadMap, otherRect, otherMask, dest);
  470.                         end;
  471.                 end;
  472.         CopyBits(offVirginMap, mainWndo^.portBits, flameRect[0], flameRect[0], srcCopy, nil);
  473.         CopyBits(offVirginMap, mainWndo^.portBits, flameRect[1], flameRect[1], srcCopy, nil);
  474.         {copy the sum bitmaps to the screen}
  475.         for index := 1 to numberOfEnemies do
  476.             with theEnemies[index] do
  477.                 CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  478.  
  479.         with theEye do
  480.             if (mode > 0) then
  481.                 begin
  482.                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, eyeRects[otherMode], eyeRects[otherMode + 5], dest);
  483.                     CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, playRgn);
  484.                     oldDest := dest;
  485.                 end;
  486.     end;
  487.  
  488. {=================================}
  489.  
  490.     procedure RedoTheBackground;
  491.         var
  492.             tempRect, anotherRect: Rect;
  493.             Pic_Handle: PicHandle;
  494.     begin
  495.         SetPort(offVirginPort);        {Set the port to my window}
  496.         Pic_Handle := GetPicture(1);    {Get Picture into memory}
  497.         SetRect(tempRect, 0, 0, 512, 342);        {left,top,right,bottom}
  498.         if (Pic_Handle <> nil) then    {Only use handle if it is valid}
  499.             begin
  500.                 ClipRect(tempRect);        {Clip picture to this rectangle}
  501.                 HLock(Handle(Pic_Handle));    {Lock the handle before using it}
  502.                 tempRect.Right := tempRect.Left + (Pic_Handle^^.picFrame.Right - Pic_Handle^^.picFrame.Left);
  503.                 tempRect.Bottom := tempRect.Top + (Pic_Handle^^.picFrame.Bottom - Pic_Handle^^.picFrame.Top);
  504.                 HUnLock(Handle(Pic_Handle));{Unlock the picture again}
  505.             end;
  506.         if (Pic_Handle <> nil) then    {Only use handle if it is valid}
  507.             DrawPicture(Pic_Handle, tempRect);{Draw this picture}
  508.         ReleaseResource(Handle(Pic_Handle));
  509.         if (numberOfStones > 2) then
  510.             begin
  511.                 tempRect := upperTombRect1;
  512.                 OffsetRect(tempRect, tombRects[3].right - tempRect.right, tombRects[3].top - tempRect.top);
  513.                 CopyBits(offPlayerMap, offVirginMap, upperTombRect1, tempRect, srcCopy, nil);
  514.                 tempRect := upperTombRect2;
  515.                 OffsetRect(tempRect, tombRects[4].left - tempRect.left, tombRects[4].top - tempRect.top);
  516.                 CopyBits(offPlayerMap, offVirginMap, upperTombRect2, tempRect, srcCopy, nil);
  517.             end;
  518.         if ((numberOfStones > 4) and (levelOn <> 3)) then
  519.             begin
  520.                 CopyBits(offEnemyMap, offVirginMap, littleTombRect, tombRects[5], srcCopy, nil);
  521.             end;
  522.         if (levelOn < 3) then
  523.             begin
  524.                 SetRect(tempRect, 166, 316, 346, 332);
  525.                 anotherRect := tempRect;
  526.                 anotherRect.left := anotherRect.left - 180;
  527.                 anotherRect.right := anotherRect.right - 180;
  528.                 CopyBits(offVirginMap, offVirginMap, tempRect, anotherRect, srcCopy, playRgn);
  529.                 anotherRect.left := anotherRect.left + 180 + 180;
  530.                 anotherRect.right := anotherRect.right + 180 + 180;
  531.                 CopyBits(offVirginMap, offVirginMap, tempRect, anotherRect, srcCopy, playRgn);
  532.             end;
  533.  
  534.         SetRect(tempRect, 0, 0, 512, 342);
  535.         CopyBits(offVirginMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, nil);
  536.     end;
  537.  
  538. {=================================}
  539.  
  540.     procedure ShowScore;
  541.         var
  542.             tempString: Str255;
  543.     begin
  544.         CopyBits(offEnemyMap, mainWndo^.portBits, scoreGrabRect, scoreDropRect, srcCopy, nil);
  545.         SetPort(mainWndo);
  546.         PenNormal;
  547.         MoveTo(261, 179);
  548.         TextFont(0);
  549.         TextSize(12);
  550.         NumToString(score, tempString);
  551.         DrawString(tempString);
  552.     end;
  553.  
  554. {=================================}
  555.  
  556.     procedure DoTheHoopla;
  557.         var
  558.             index, index2, index3, tempNum: Integer;
  559.             dummyLong: LongInt;
  560.             theseAhnks: array[1..24] of Rect;
  561.             ahnkModes: array[1..24] of Integer;
  562.     begin
  563.         ShowScore;
  564.         tempNum := mortals;
  565.         if (tempNum > 24) then
  566.             tempNum := 24;
  567.         for index := 1 to tempNum do
  568.             begin
  569.                 SetRect(theseAhnks[index], (239 - (mortals * 10) + (index * 20)), 200, (254 - (mortals * 10) + (index * 20)), 224);
  570.                 CopyMask(offPlayerMap, offPlayerMap, mainWndo^.portBits, ankRects[0, 0], ankRects[0, 1], theseAhnks[index]);
  571.                 DoTheSound('flip.snd', TRUE);
  572.                 ahnkModes[index] := 0;
  573.                 for index2 := 1 to 30 do
  574.                     for index3 := 1 to index do
  575.                         begin
  576.                             ahnkModes[index3] := ahnkModes[index3] + 1;
  577.                             if (ahnkModes[index3] > 15) then
  578.                                 ahnkModes[index3] := 0;
  579.                             CopyBits(offVirginMap, offLoadMap, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  580.                             CopyMask(offPlayerMap, offPlayerMap, offLoadMap, ankRects[ahnkModes[index3], 0], ankRects[ahnkModes[index3], 1], theseAhnks[index3]);
  581.                             CopyBits(offLoadMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  582.                         end;
  583.             end;
  584.         for index2 := 1 to 50 do
  585.             for index3 := 1 to tempNum do
  586.                 begin
  587.                     if (ahnkModes[index3] <> 0) then
  588.                         ahnkModes[index3] := ahnkModes[index3] + 1;
  589.                     if (ahnkModes[index3] > 15) then
  590.                         begin
  591.                             DoTheSound('ahnk.snd', TRUE);
  592.                             ahnkModes[index3] := 0;
  593.                         end;
  594.                     CopyBits(offVirginMap, offLoadMap, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  595.                     CopyMask(offPlayerMap, offPlayerMap, offLoadMap, ankRects[ahnkModes[index3], 0], ankRects[ahnkModes[index3], 1], theseAhnks[index3]);
  596.                     CopyBits(offLoadMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  597.                 end;
  598.         for index3 := 1 to tempNum do
  599.             CopyBits(offVirginMap, mainWndo^.portBits, theseAhnks[index3], theseAhnks[index3], srcCopy, nil);
  600.     end;
  601.  
  602. {=================================}
  603.  
  604.     procedure CheckExtraMortal;
  605.     begin
  606.         if (score > nextMortal) then
  607.             begin
  608.                 DoTheSound('bonus.snd', FALSE);    {You got an extra player!}
  609.                 mortals := mortals + 1;
  610.                 nextMortal := nextMortal + 20000;
  611.             end;
  612.     end;
  613.  
  614. {=================================}
  615.  
  616.     procedure ReDrawHiScores;
  617.         var
  618.             index: Integer;
  619.             dummyLong: LongInt;
  620.             tempRect: Rect;
  621.             dummyString: Str255;
  622.     begin
  623.         SetPort(offLoadPort);
  624.         PenNormal;
  625.         SetRect(tempRect, 170, 100, 347, 280);
  626.         FillRect(tempRect, black);
  627.         TextFont(0);
  628.         TextSize(12);
  629.         TextMode(srcXOr);
  630.         MoveTo(184, 125);
  631.         DrawString('Glypha 3.0 High Scores');
  632.         TextFont(1);
  633.         TextSize(9);
  634.         for index := 1 to 10 do    {Now we're going to loop through all the scores    }
  635.             begin
  636.                 MoveTo(185, index * 14 + 129);            {Moving the pen down each time    }
  637.                 DrawString(hiStrings[index]);                {Draw the name of person        }
  638.                 MoveTo(290, index * 14 + 129);            {Move pen over to the right        }
  639.                 NumToString(hiScores[index], dummyString);
  640.                 DrawString(dummyString);                        {And draw their score            }
  641.             end;                            {Copy the screen to the virgin port for updates    }
  642.         tempRect.top := tempRect.bottom;
  643.         for index := 1 to 86 do
  644.             begin
  645.                 tempRect.top := tempRect.top - 2;
  646.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, nil);
  647.                 Delay((delayFor + 2) div 2, dummyLong);
  648.             end;
  649.  
  650.         CopyBits(mainWndo^.portBits, offVirginMap, mainWndo^.portRect, mainWndo^.portRect, srcCopy, nil);
  651.     end;
  652.  
  653. {=================================}
  654.  
  655.     procedure ReadInScores;
  656.         type
  657.             scoreHandle = ^scorePtr;
  658.             scorePtr = ^score;
  659.             score = record
  660.                     data: array[0..9] of LongInt;
  661.                 end;
  662.  
  663.             nameHandle = ^namePtr;
  664.             namePtr = ^name;
  665.             name = record
  666.                     data: array[0..9, 0..14] of Char;
  667.                 end;
  668.  
  669.             prefHandle = ^prefPtr;
  670.             prefPtr = ^pref;
  671.             pref = record
  672.                     data: array[0..31] of Char;
  673.                 end;
  674.  
  675.         var
  676.             index, index2: Integer;
  677.             dummyStr: Str255;
  678.             theScores: scoreHandle;
  679.             theNames: nameHandle;
  680.             thePrefs: prefHandle;
  681.  
  682.     begin
  683.         theScores := scoreHandle(NewHandle(SIZEOF(score)));
  684.         MoveHHi(Handle(theScores));
  685.         HLock(Handle(theScores));
  686.         Handle(theScores) := GetResource('scrs', 128);
  687.         for index := 0 to 9 do
  688.             hiScores[index + 1] := theScores^^.data[index];
  689.         ReleaseResource(Handle(theScores));
  690.         HUnlock(Handle(theScores));
  691.         DisposHandle(Handle(theScores));
  692.  
  693.         theNames := nameHandle(NewHandle(SIZEOF(name)));
  694.         MoveHHi(Handle(theNames));
  695.         HLock(Handle(theNames));
  696.         Handle(theNames) := GetResource('name', 128);
  697.         for index := 0 to 9 do
  698.             begin
  699.                 dummyStr := '';
  700.                 for index2 := 0 to 14 do
  701.                     dummyStr := CONCAT(dummyStr, theNames^^.data[index, index2]);
  702.                 hiStrings[index + 1] := dummyStr;
  703.             end;
  704.         ReleaseResource(Handle(theNames));
  705.         HUnlock(Handle(theNames));
  706.         DisposHandle(Handle(theNames));
  707.  
  708.         thePrefs := prefHandle(NewHandle(SIZEOF(pref)));
  709.         MoveHHi(Handle(thePrefs));
  710.         HLock(Handle(thePrefs));
  711.         Handle(thePrefs) := GetResource('pref', 128);
  712.  
  713.         if (thePrefs^^.data[0] = 'M') then
  714.             keyboardControl := FALSE
  715.         else
  716.             keyboardControl := TRUE;
  717.         if (thePrefs^^.data[1] = 'S') then
  718.             soundOn := TRUE
  719.         else
  720.             soundOn := FALSE;
  721.         if (inhibitSound) then
  722.             soundOn := FALSE;
  723.  
  724.         case thePrefs^^.data[2] of
  725.             'L': 
  726.                 delayFor := slowest;
  727.             'S': 
  728.                 delayFor := slow;
  729.             'F': 
  730.                 delayFor := fast;
  731.             'A': 
  732.                 delayFor := fastest;
  733.             otherwise
  734.                 begin
  735.                 end;
  736.         end;
  737.  
  738.         nameUsing := '';
  739.         for index := 1 to 15 do
  740.             nameUsing := CONCAT(nameUsing, thePrefs^^.data[index + 16]);
  741.  
  742.         ReleaseResource(Handle(thePrefs));
  743.         HUnlock(Handle(thePrefs));
  744.         DisposHandle(Handle(thePrefs));
  745.  
  746.         scoresChanged := FALSE;
  747.     end;
  748.  
  749. {=================================}
  750.  
  751.     procedure WriteOutScores;
  752.         type
  753.             scoreHandle = ^scorePtr;
  754.             scorePtr = ^score;
  755.             score = record
  756.                     data: array[0..9] of LongInt;
  757.                 end;
  758.  
  759.             nameHandle = ^namePtr;
  760.             namePtr = ^name;
  761.             name = record
  762.                     data: array[0..9, 0..14] of Char;
  763.                 end;
  764.  
  765.             prefHandle = ^prefPtr;
  766.             prefPtr = ^pref;
  767.             pref = record
  768.                     data: array[0..31] of Char;
  769.                 end;
  770.  
  771.         var
  772.             index, index2: Integer;
  773.             dummyStr: Str255;
  774.             theScores: scoreHandle;
  775.             theNames: nameHandle;
  776.             thePrefs: prefHandle;
  777.  
  778.     begin
  779.         thePrefs := prefHandle(NewHandle(SIZEOF(pref)));
  780.         HLock(Handle(thePrefs));
  781.         Handle(thePrefs) := GetResource('pref', 128);
  782.         if (keyboardControl) then
  783.             thePrefs^^.data[0] := 'K'
  784.         else
  785.             thePrefs^^.data[0] := 'M';
  786.         if (soundOn) then
  787.             thePrefs^^.data[1] := 'S'
  788.         else
  789.             thePrefs^^.data[1] := 'N';
  790.  
  791.         case delayFor of
  792.             slowest: 
  793.                 thePrefs^^.data[2] := 'L';
  794.             slow: 
  795.                 thePrefs^^.data[2] := 'S';
  796.             fast: 
  797.                 thePrefs^^.data[2] := 'F';
  798.             fastest: 
  799.                 thePrefs^^.data[2] := 'A';
  800.             otherwise
  801.                 begin
  802.                 end;
  803.         end;
  804.  
  805.         for index := 1 to 15 do
  806.             thePrefs^^.data[index + 16] := COPY(nameUsing, index, 1);
  807.         ChangedResource(Handle(thePrefs));
  808.         WriteResource(Handle(thePrefs));
  809.         ReleaseResource(Handle(thePrefs));
  810.         HUnlock(Handle(thePrefs));
  811.         DisposHandle(Handle(thePrefs));
  812.  
  813.         if (scoresChanged) then
  814.             begin
  815.                 theScores := scoreHandle(NewHandle(SIZEOF(score)));
  816.                 MoveHHi(Handle(theScores));
  817.                 HLock(Handle(theScores));
  818.                 Handle(theScores) := GetResource('scrs', 128);
  819.                 for index := 0 to 9 do
  820.                     theScores^^.data[index] := hiScores[index + 1];
  821.                 ChangedResource(Handle(theScores));
  822.                 WriteResource(Handle(theScores));
  823.                 ReleaseResource(Handle(theScores));
  824.                 HUnlock(Handle(theScores));
  825.                 DisposHandle(Handle(theScores));
  826.  
  827.                 theNames := nameHandle(NewHandle(SIZEOF(name)));
  828.                 HLock(Handle(theNames));
  829.                 Handle(theNames) := GetResource('name', 128);
  830.                 for index := 0 to 9 do
  831.                     for index2 := 0 to 14 do
  832.                         theNames^^.data[index, index2] := COPY(hiStrings[index + 1], index2 + 1, 1);
  833.                 ChangedResource(Handle(theNames));
  834.                 WriteResource(Handle(theNames));
  835.                 ReleaseResource(Handle(theNames));
  836.                 HUnlock(Handle(theNames));
  837.                 DisposHandle(Handle(theNames));
  838.             end;
  839.     end;
  840.  
  841. {=================================}
  842.  
  843.     procedure FinalScore;
  844.         var
  845.             index, ranking: Integer;
  846.     begin
  847.         FlushEvents(everyEvent, 0);                                    {Clear all the keystrokes    }
  848.         if (score > hiScores[10]) and (mortalsStart = defaultNum) then        {Is it a high score?            }
  849.             begin
  850.                 scoresChanged := TRUE;                        {Mark scores as changed            }
  851.                 DoTheSound('bonus.snd', FALSE);        {Play the bonus sound.            }
  852.                 ranking := 10;                                        {And sort through the high    }
  853.                 for index := 9 downto 1 do                {scores to find the players    }
  854.                     begin                                                        {ranking.                                        }
  855.                         if (score > hiScores[index]) then
  856.                             ranking := index;
  857.                     end;
  858.                 for index := 10 downto ranking + 1 do
  859.                     begin
  860.                         hiScores[index] := hiScores[index - 1];        {Move everyone's score}
  861.                         hiStrings[index] := hiStrings[index - 1];    {down the list.                }
  862.                     end;
  863.                 hiScores[ranking] := score;
  864.                 SetPort(mainWndo);
  865.                 WhosHiScore(nameUsing);
  866.                 hiStrings[ranking] := nameUsing;
  867.             end;
  868.     end;
  869.  
  870. {=================================}
  871.  
  872.     procedure DoHelpScreen;
  873.         var
  874.             index: Integer;
  875.             tempRect, dropRect: Rect;
  876.             Pic_Handle: PicHandle;
  877.             theEvent: EventRecord;
  878.     begin
  879.         SetPort(offLoadPort);
  880.         Pic_Handle := GetPicture(2000);
  881.         SetRect(tempRect, 0, 0, 360, 338);
  882.         if (Pic_Handle <> nil) then
  883.             begin
  884.                 ClipRect(tempRect);
  885.                 HLock(Handle(Pic_Handle));
  886.                 tempRect.Right := tempRect.Left + (Pic_Handle^^.picFrame.Right - Pic_Handle^^.picFrame.Left);
  887.                 tempRect.Bottom := tempRect.Top + (Pic_Handle^^.picFrame.Bottom - Pic_Handle^^.picFrame.Top);
  888.                 HUnLock(Handle(Pic_Handle));
  889.             end;
  890.         if (Pic_Handle <> nil) then
  891.             DrawPicture(Pic_Handle, tempRect);
  892.         ReleaseResource(Handle(Pic_Handle));
  893.         SetRect(tempRect, 0, 0, 1023, 1023);
  894.         ClipRect(tempRect);
  895.         SetRect(dropRect, 168, 278, 348, 278);
  896.         SetRect(tempRect, 0, 169, 180, 169);
  897.         for index := 1 to 169 do
  898.             begin
  899.                 dropRect.top := dropRect.top - 1;
  900.                 tempRect.top := tempRect.top - 1;
  901.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  902.             end;
  903.         SetRect(dropRect, 168, 109, 348, 278);
  904.         SetRect(tempRect, 0, 0, 180, 169);
  905.         FlushEvents(everyEvent, 0);
  906.         SetEventMask(playMask);
  907.         repeat
  908.         until (GetNextEvent(playMask, theEvent));
  909.         for index := 1 to 180 do
  910.             begin
  911.                 tempRect.left := tempRect.left + 1;
  912.                 tempRect.right := tempRect.right + 1;
  913.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  914.             end;
  915.         FlushEvents(everyEvent, 0);
  916.         repeat
  917.         until (GetNextEvent(playMask, theEvent));
  918.         for index := 1 to 169 do
  919.             begin
  920.                 tempRect.top := tempRect.top + 1;
  921.                 tempRect.bottom := tempRect.bottom + 1;
  922.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  923.             end;
  924.         FlushEvents(everyEvent, 0);
  925.         repeat
  926.         until (GetNextEvent(playMask, theEvent));
  927.         for index := 1 to 180 do
  928.             begin
  929.                 tempRect.left := tempRect.left - 1;
  930.                 tempRect.right := tempRect.right - 1;
  931.                 CopyBits(offLoadMap, mainWndo^.portBits, tempRect, dropRect, srcCopy, nil);
  932.             end;
  933.         FlushEvents(everyEvent, 0);
  934.         repeat
  935.         until (GetNextEvent(playMask, theEvent));
  936.         SetEventMask(EveryEvent);
  937.         RedrawHiScores;
  938.     end;
  939.  
  940. {=================================}
  941.  
  942.     procedure FlushTheScores;
  943.         var
  944.             index: Integer;
  945.     begin
  946.         for index := 1 to 10 do
  947.             begin
  948.                 hiScores[index] := 0;
  949.                 hiStrings[index] := 'Play Me .......';
  950.             end;
  951.         scoresChanged := TRUE;
  952.         RedrawHiScores;
  953.     end;
  954.  
  955. {=================================}
  956.  
  957. end.